package com.jintian.smart.kernel.common.util;

import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

@Component
public class HomeUtil {
    private static final File appHomeFile;
    private static final Pattern BOOTSTRAP_PATTERN = Pattern.compile("smart-boot(-[0-9]+\\.[0-9]+\\.[0-9]+((\\-SNAPSHOT)|(-RC[0-9]+))?)?\\.jar");
    private static final Pattern LOADER_PATTERN = Pattern.compile("loader.properties");

    static {
        String home = System.getProperty("APP_HOME", System.getenv("APP_HOME"));
        File configPath;
        if (StringUtil.isNotBlank(home)) {
            configPath = new File(home);
        } else {
            configPath = locateAppHome();
        }

        File homeFile = null;
        try {
            homeFile = configPath.getCanonicalFile();
        } catch (IOException ioe) {
            homeFile = configPath.getAbsoluteFile();
        }
        appHomeFile = homeFile;
        System.setProperty("APP_HOME", appHomeFile.getPath());
        System.out.println("APP_HOME\t= " + appHomeFile.getPath());
    }

    public static String getAppHome() {
        return appHomeFile.getPath();
    }

    public static String getConfigPath() {
        String config = getAppHome() + File.separator + "conf";
        return config;
    }

    public static String getLogPath() {
        String config = getAppHome() + File.separator + "log";
        return config;
    }

    public static String getOssPath() {
        String appHome = getAppHome();
        if (appHome == null) {
            appHome = System.getenv("SMART_FILEVIEW_BIN_FOLDER");
        }

        String config = appHome + File.separator + "oss";
        return config;
    }

    public static String getWebPath() {
        String config = getAppHome() + File.separator + "web";
        return config;
    }

    public static String getModelPath() {
        String config = getAppHome() + File.separator + "model";
        return config;
    }

    private static File locateAppHome() {
        String[] file = matchAppHome(BOOTSTRAP_PATTERN);
        if (file == null || file.length == 0) {
            file = matchAppHome(LOADER_PATTERN);
        }
        if (file == null || file.length == 0) {
            throw new RuntimeException("未探测到 APP_HOME 位置，请配置 APP_HOME 环境变量");
        }

        String targetPath = null;
        for (String path : file) {
            if (path.contains("smart-system") && !path.contains("target") && targetPath == null) {
                targetPath = path;
            } else if (!path.contains("target")) {
                targetPath = path;
                break;
            }
        }
        File configPath = new File(targetPath).getParentFile().getParentFile();
        return configPath;
    }

/*    private static String[] matchAppHome(Pattern pattern) {
        String userDir = System.getProperty("user.dir");
        String[] file = new File(userDir).list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return pattern.matcher(name).matches();
            }
        });
        return file;
    }*/

    public static String[] matchAppHome(Pattern pattern) {
        List<String> matchedFiles = new ArrayList<>();
        Path startPath = Paths.get(System.getProperty("user.dir"));

        try {
            Files.walkFileTree(startPath, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
                    if (pattern.matcher(file.getFileName().toString()).matches()) {
                        matchedFiles.add(file.toAbsolutePath().toString());
                    }
                    return FileVisitResult.CONTINUE;
                }
            });
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return matchedFiles.toArray(new String[0]);
    }
}
